package com.moon.back.service.impl.handler;

import cn.dev33.satoken.util.SaResult;
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.dictionary.CoreSynonymDictionary;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.common.Term;
import com.moon.back.entity.Resp.FileCommandOpreaResp;
import com.moon.back.entity.dto.FileOperaDto;
import com.moon.back.service.HanLpService;
import com.moon.back.service.IFileService;
import com.moon.back.service.impl.file.FileServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class HanLpServiceImpl implements HanLpService {


    static {
        //        HanLP.Config.enableDebug();data/model/dependency/NNParserModel.txt
        //   加载神经网络依存句法模型[data/model/dependency/NNParserModel.txt]失败！
        HanLP.Config.NNParserModelPath  = "D:\\bishe\\moon_back\\moon_db\\data\\model\\dependency\\NNParserModel.txt";
        HanLP.Config.PerceptronCWSModelPath = "D:\\bishe\\moon_back\\moon_db\\data\\model\\perceptron\\large\\cws.bin";
        HanLP.Config.PerceptronPOSModelPath = "D:\\bishe\\moon_back\\moon_db\\data\\model\\perceptron\\pku1998\\pos.bin";
        HanLP.Config.PerceptronNERModelPath = "D:\\bishe\\moon_back\\moon_db\\data\\model\\perceptron\\pku1998\\ner.bin";
    }

    // 定义一个查找合格的数值
    public static BigDecimal TO_GET_VALUE = new BigDecimal("0.99");

    public static String[] CONTAINS_JU = new String[]{"包含","其中含有","开头","结尾"};
    // 排除移操作                                                         "移动"
    public static String[] OPERA_SIGNS = new String[]{"查询","修改","重命名","删除"};

    public static String[] OBJ_STR = new String[]{"文件","文件夹"};


    @Resource
    private IFileService fileService =new FileServiceImpl();

    @Override
    public SaResult HanLpInput(String text) {
        return this.HanLpHanlder(text);
    }

    public static void main(String[] args) {

        String text = "将文件名为test的文件修改为test2";
        new HanLpServiceImpl().HanLpHanlder(text);

    }

    /**
     * 分析语句 语义相似度分析
     * @param text
     */
    @Override
    public SaResult HanLpHanlder(String text) {

        // 1. 加载词向量模型（需提前下载）
        // 2. 计算词语相似度
        if(text.contains("移动")){
            log.info("抱歉，移动功能暂不支持");
            FileCommandOpreaResp fileCommandOpreaResp = new FileCommandOpreaResp();
            fileCommandOpreaResp.setMsg("抱歉，移动功能暂不支持");
            return SaResult.data(fileCommandOpreaResp);
        }


        // 创建分词器
        Segment segment = HanLP.newSegment();
        // 对文本进行分词
        List<Term> termList = segment.seg(text);

        FileOperaDto fileOperaDto = new FileOperaDto();

        boolean[] getFlags = new boolean[3];

        // 遍历分词结果
        log.info("词性分析:");
        fileOperaDto.setIsContainOpera(Boolean.FALSE);
        fileOperaDto.setIsContainType(-1);

        for (Term term : termList) {
            log.info("{} ---- {}", term.word, term.nature);
            String nature = term.nature.toString();

            if("v".equals(nature)){
                BigDecimal operaSignMax = new BigDecimal("0.0");
                for (int i = 0; i< OPERA_SIGNS.length; i++) {

                    double similarity = CoreSynonymDictionary.similarity(OPERA_SIGNS[i], term.word);
                    // 词义的相似度
                    BigDecimal bigDecimal = BigDecimal.valueOf(similarity);
                    log.info("term.word: {} OPERA_SIGNS[i]: {} simailier: {}", term.word, OPERA_SIGNS[i], bigDecimal);
                    if(bigDecimal.compareTo(operaSignMax)>0){
                        // 操作类型标记
                        operaSignMax = bigDecimal;
                        fileOperaDto.setOperaSign(i);
                        getFlags[0]  = Boolean.TRUE;
                    }
                }

                containAyalyst(fileOperaDto, getFlags, term);

            }else if("nx".equals(nature)){
                getFlags[2]  = Boolean.TRUE;
                fileOperaDto.setFileNameStr(term.word);

            }else if(nature.contains("n")){


                containAyalyst(fileOperaDto, getFlags, term);
                if(getFlags[2]) {
                    continue;
                }
                BigDecimal bigDecimalMax = BigDecimal.valueOf(1.00);
                for (String s : OBJ_STR) {
                    if (term.word.contains(s)) {
                        continue;
                    }
                    double similarity = CoreSynonymDictionary.similarity(s, term.word);
                    // 词义的相似度
                    BigDecimal bigDecimal = BigDecimal.valueOf(similarity);

                    if (  bigDecimalMax.compareTo(bigDecimal)>0 ) {
                        // 操作类型标记
                        bigDecimalMax = bigDecimal;
                        getFlags[2]  = Boolean.TRUE;
                        fileOperaDto.setFileNameStr(term.word);
                    }

                }
            }

        }

        if(!(getFlags[0] && getFlags[1] && getFlags[2] ) ){
            log.info("抱歉，后台无法解析改指令，请重新输入");
            FileCommandOpreaResp fileCommandOpreaResp = new FileCommandOpreaResp();
            fileCommandOpreaResp.setMsg("抱歉，后台无法解析改指令，请重新输入");
            return SaResult.data(fileCommandOpreaResp);
        }

        log.info("指令解析成功");
        log.info("fileOperaDto: {}", fileOperaDto);



         // 依存关系 暂时不做分析
//        System.out.println("依存关系分析:");
//        log.info(String.valueOf(System.currentTimeMillis()));
//        IDependencyParser parser = new NeuralNetworkDependencyParser();
//        List<Term> terms = StandardTokenizer.segment(text);
//        CoNLLSentence parse = parser.parse(terms);
//
//        CoNLLWord[] wordArray = parse.getWordArray();
//        for (CoNLLWord coNLLWord : wordArray) {
//            System.out.println(coNLLWord);
//        }
//
//        log.info(String.valueOf(System.currentTimeMillis()));
        return fileService.fileMatchHandler(fileOperaDto);
    }

    private void containAyalyst(FileOperaDto fileOperaDto, boolean[] getFlags, Term term) {
        for (int i = 0; i< CONTAINS_JU.length; i++) {

            double similarity = CoreSynonymDictionary.similarity(CONTAINS_JU[i], term.word);
            // 词义的相似度
            BigDecimal bigDecimal = BigDecimal.valueOf(similarity);
            log.info("term.word: {}CONTAINS_JU[i]: {} simailier: {}", term.word, CONTAINS_JU[i], bigDecimal);

            if(bigDecimal.compareTo(TO_GET_VALUE)>0){
                // 操作类型标记
                fileOperaDto.setIsContainOpera(Boolean.TRUE);
                fileOperaDto.setIsContainType(i);
                log.info("包含类型: {}", CONTAINS_JU[i]);
                getFlags[1]  = Boolean.TRUE;
            }

        }
    }

    @Override
    public void HanLpOutput(String text) {
    }

    @Override
    public void RegexHandler(String text) {

    }


    public Boolean FileHandler(String text){
//        fileService

        return Boolean.FALSE;

    }

}
